﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Rechargeable.Products;
using Rechargeable.Machines;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.Users;
using Rechargeable.Games;

namespace Rechargeable.EntityFrameworkCore
{
    public static class RechargeableDbContextModelCreatingExtensions
    {
        public static void ConfigureRechargeable(this ModelBuilder builder)
        {
            Check.NotNull(builder, nameof(builder));

            /* Configure your own tables/entities inside here */

            //builder.Entity<YourEntity>(b =>
            //{
            //    b.ToTable(RechargeableConsts.DbTablePrefix + "YourEntities", RechargeableConsts.DbSchema);

            //    //...
            //});
            #region Products
            builder.Entity<Product>(b =>
            {
                b.ToTable(RechargeableConsts.DbTablePrefix + "Products", RechargeableConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(x => x.Name).IsRequired().HasMaxLength(256);
                b.Property(x => x.GameName).IsRequired().HasMaxLength(256);
                b.Property(x => x.Desc).IsRequired().HasMaxLength(256);
                b.Property(x => x.Version).IsRequired().HasMaxLength(128).HasDefaultValue("1.0.0.0");
                b.HasMany(x => x.ProductPrices)
                .WithOne(pp => pp.Product)
                .HasPrincipalKey(x => x.Id)
                .HasForeignKey(x => x.ProductId);
            });

            builder.Entity<ProductPrice>(b =>
            {
                b.ToTable(RechargeableConsts.DbTablePrefix + "ProductPrices", RechargeableConsts.DbSchema);
                b.Property(x => x.Day).IsRequired();
                b.Property(x => x.Desc).HasMaxLength(256);
                b.Property(x => x.Money).IsRequired();
                b.Property(x => x.ProductId).IsRequired();
            });
            #endregion

            builder.Entity<Machine>(b =>
            {
                b.ToTable(RechargeableConsts.DbTablePrefix + "Machines", RechargeableConsts.DbSchema);
                b.ConfigureByConvention();
                b.Property(x => x.AutoRecharge).IsRequired().HasDefaultValue<bool>(true);
                b.Property(x => x.DriveId).HasMaxLength(128).IsRequired();
                b.Property(x => x.ExpireTime).IsRequired();
                b.Property(x => x.Name).HasMaxLength(256);
                b.Property(x => x.ProductId).IsRequired();
                b.Property(x => x.UserId).IsRequired();
                b.HasIndex(x => x.ProductId);
                b.HasIndex(x => x.UserId);
                b.HasIndex(x => new { x.UserId, x.ProductId });

                b.HasMany(x => x.MachineRecords)
                .WithOne(mr => mr.Machine)
                .HasPrincipalKey(x => x.Id)
                .HasForeignKey(x => x.MachineId);
            });

            builder.Entity<MachineRecord>(b =>
            {
                b.ToTable(RechargeableConsts.DbTablePrefix + "MachineRecords", RechargeableConsts.DbSchema);
                b.Property(x => x.Desc).IsRequired().HasMaxLength(1024);
                b.HasIndex(x => x.MachineId);
            });

            builder.Entity<SerialNumber>(b =>
            {
                b.ToTable(RechargeableConsts.DbTablePrefix + "SerialNumbers", RechargeableConsts.DbSchema);
                b.ConfigureFullAudited();
                b.HasIndex(x => x.BuyUserId);
                b.HasIndex(x => x.SaleUserId);
                b.HasIndex(x => x.ProductId);
                b.HasIndex(x => new { x.BuyUserId, x.SaleUserId, x.ProductId });
            });

            builder.Entity<GameAccount>(b =>
            {
                b.ToTable(RechargeableConsts.DbTablePrefix + "GameAccounts", RechargeableConsts.DbSchema);
                b.ConfigureByConvention();
                b.HasIndex(x => x.LoginName);
                b.HasIndex(x => x.ProductId);
                b.HasIndex(x => new { x.LoginName, x.ProductId });
            });

            builder.Entity<CardInformation>(b =>
            {
                b.ToTable(RechargeableConsts.DbTablePrefix + "CardInformations", RechargeableConsts.DbSchema);
                b.ConfigureByConvention();
            });
        }

        public static void ConfigureCustomUserProperties<TUser>(this EntityTypeBuilder<TUser> b)
            where TUser : class, IUser
        {
            //b.Property<string>(nameof(AppUser.MyProperty))...
        }
    }
}